/*
 * ProductDAO.java
 *
 * Created on March 29, 2007, 8:57 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.mystuff.sales;


import edu.byu.isys413.mystuff.Cache;
import edu.byu.isys413.mystuff.ConnectionPool;
import edu.byu.isys413.mystuff.ConnectionPoolException;
import edu.byu.isys413.mystuff.DataException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 *
 * @author Gabe
 */
public abstract class ProductDAO {
    
    /** Contains a singleton instance of ProductDAO*/
    private static ProductDAO instance = null;
    
    public static synchronized ProductDAO getInstance(){
        return instance;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    /////////   CREATE
    /** This requires each extending class to have a create method*/
    public abstract ProductBO create() throws Exception;
    
    
    //////////////////////////////////////////////////////////////////////////////
    //////////   READ
    /**
     *
     */
    public abstract ProductBO read(String id) throws SQLException, DataException, ConnectionPoolException;
    
    
    
    
    /**/
    public abstract ArrayList<ProductBO> readAll() throws SQLException, DataException, ConnectionPoolException;
    /**/
   // public abstract ProductBO readSku(String id,Connection conn) throws SQLException, DataException;
    
    
    public synchronized ProductBO read(String id, Connection conn) throws SQLException, DataException{
        Cache c = Cache.getInstance();                                          // check to see if id in the cache
        ProductBO productBO = (ProductBO)c.get(id);                             //make a productBO with the productid
        
        PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM Product WHERE ProductID =?");
        pstmt.setString(1,id);
        ResultSet rs = pstmt.executeQuery();
        
        if (rs.next()) {
            productBO.setProductId(rs.getString("ProductID"));
            productBO.setPrice(rs.getDouble("Price"));
            productBO.setSku(rs.getString("SKU"));
            productBO.setAlreadyInDatabase(true);
            productBO.setDirty(false);
            
            c.put(productBO.getProductId(), productBO); // save to the cache
        }else{
            throw new DataException("Object was not found in the database.");
        }
        return productBO;
    }
    
    //////////////////////////////////
    ///   UPDATE
    
    /**
     * This is the public save method.  It is what is called when
     * the user (controller) code wants to save or update an object
     * into the database.
     */
    public synchronized void save(ProductBO productBO) throws SQLException, DataException {
        Connection conn = null;
        try {
            conn = ConnectionPool.getInstance().get();
            save(productBO, conn);
            ConnectionPool.getInstance().release(conn);
        }catch (Exception ex) {
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throw new DataException("Could not save the record");
        }
    }
    
    /**
     *
     */
    synchronized void save(ProductBO ProductBO, Connection conn) throws SQLException, DataException {
//            try {
//                // check the dirty flag in the object.  if it is dirty,
//                // run update or insert
//                if (productBo.isDirty()) {
//                    if (cust.isAlreadyInDB()) {
//                        update(cust, conn);
//                    }else{
//                        insert(productBO, conn);
//                    }
//                    // set the dirty flag to false now that we've saved it
//                    productBO.setDirty(false);
//                    Cache c = Cache.getInstance();
//                    c.touch(productBO.getId());
//                }
//            } catch (DataException ex) {
//                throw ex;
//            } catch (SQLException ex) {
//                throw ex;
//            }
        
    }
    
//    private void insertIntoProduct(ProductBO productBO, Connection conn) throws SQLException, DataException{
//        
//        
////            PreparedStatement pstmt = conn.prepareStatement("INSERT INTO Product (ProductID, " +
////                    "Price, prodtype, SKU) VALUES (?, ?, ?, ?)");
////            pstmt.setString(1, productBO.getProductID());
////            pstmt.setDouble(2, productBO.getPrice());
////            pstmt.setString(3, productBO.getProdType());
////            pstmt.setString(4, productBO.getSKU());
////
////            pstmt.execute();
//    }
    
    /**
     *
     */
    // abstract void update(ProductBO productBO, Connection conn) throws SQLException, DataException;
    
    
    /**
     *
     */
    abstract void insert(ProductBO productBO, Connection conn) throws SQLException, DataException;
    
    
    
    ///////////////////////////////////////////////////////////////////////////////
    /////////   DELETE
    
    //I did not include the DELETE functionality intentionally due to instructions received, as well as
    //to protect the integrity of the data.
    
}
